package com.snapan.service.impl;

import com.snapan.dao.EmailVerificationDao;
import com.snapan.entity.EmailVerification;
import com.snapan.service.EmailService;
import com.snapan.service.VerificationCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.Random;

@Service
public class VerificationCodeServiceImpl implements VerificationCodeService {

    @Autowired
    private EmailVerificationDao emailVerificationDao;

    @Autowired
    private EmailService emailService;

    // 验证码长度
    private static final int CODE_LENGTH = 6;
    // 验证码有效期（分钟）
    private static final int EXPIRE_MINUTES = 10;
    // 发送频率限制（分钟）
    private static final int FREQUENCY_LIMIT_MINUTES = 1;

    @Override
    public boolean generateAndSendCode(String email, Byte type) {
        try {
            // 1. 生成随机验证码
            String verificationCode = generateRandomCode();

            // 2. 计算过期时间
            Date expireTime = calculateExpireTime();

            // 3. 创建验证码记录
            EmailVerification record = new EmailVerification();
            record.setEmail(email);
            record.setVerificationCode(verificationCode);
            record.setType(type);
            record.setExpireTime(expireTime);
            record.setUsed((byte) 0); // 0-未使用
            record.setCreateTime(new Date());

            // 4. 保存到数据库
            int result = emailVerificationDao.insert(record);

            if (result > 0) {
                // 5. 发送邮件
                return emailService.sendVerificationCode(email, verificationCode, type);
            }

            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean verifyCode(String email, String userInputCode, Byte type) {
        try {
            // 查找有效的验证码记录
            EmailVerification record = emailVerificationDao.findValidCode(
                    email, userInputCode, type, new Date());

            if (record == null) {
                return false; // 验证失败：验证码不存在、已使用、已过期或类型不匹配
            }

            // 标记为已使用
            emailVerificationDao.markAsUsed(record.getId());

            return true; // 验证成功
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean isTooFrequent(String email, Byte type) {
        try {
            Integer count = emailVerificationDao.countRecentRequests(
                    email, type, getTimeBeforeMinutes(FREQUENCY_LIMIT_MINUTES));
            return count != null && count > 0;
        } catch (Exception e) {
            e.printStackTrace();
            return true; // 出现异常时限制发送，保证安全
        }
    }

    @Override
    @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行清理
    public void cleanExpiredCodes() {
        try {
            emailVerificationDao.deleteExpired();
            System.out.println("已清理过期验证码");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成随机验证码（6位数字）
     */
    private String generateRandomCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < CODE_LENGTH; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }

    /**
     * 计算过期时间
     */
    private Date calculateExpireTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, EXPIRE_MINUTES);
        return calendar.getTime();
    }

    /**
     * 获取指定分钟前的时间
     */
    private Date getTimeBeforeMinutes(int minutes) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -minutes);
        return calendar.getTime();
    }
}